﻿/*

    This file is a part of BinaryDialog.
 
    BiLog IM aka BinaryDialog - WPF Client for XMPP Protocol
    Copyright (C) 2008  Christophe LEMOINE

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Serialization;
using System.Reflection;
using System.IO;
using System.Text.RegularExpressions;

using BinaryDialog;
using BinaryDialog.Properties;
using BinaryDialog.Core;
using BinaryDialog.Core.UI;
using BinaryDialog.Core.Relationship;
using BinaryDialog.Datas;
using BinaryDialog.Core.Graphics;

namespace BinaryDialog
{

    public partial class Start : Window
    {

        private string AppPath = string.Empty;
        private string AccountsFilePath = string.Empty;

        [XmlArray(ElementName = "Accounts"), XmlArrayItem(ElementName = "Account")]
        private List<Account> m_Accounts = null;
        public List<Account> Accounts { get { return this.m_Accounts; } }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            bool Glass = false;
            if (Settings.Default.DefaultGlassAuthorization) { Glass = WindowGlassEffect.Set(this, false); }
            if (!Glass) { this.Background = new SolidColorBrush(Settings.Default.DefaultColor); }
        }

        public Start()
        {
            this.AppPath = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).TrimStart("file:\\".ToCharArray()) + System.IO.Path.DirectorySeparatorChar.ToString();
            this.AccountsFilePath = this.AppPath + Settings.Default.DefaultDatasDirectory + System.IO.Path.DirectorySeparatorChar.ToString() + Settings.Default.DefaultAccountsFilename;
            BinaryDialog.Core.Win32.Registry.Associate(this.GetType().Assembly.Location, "accounts");
            if (!Directory.Exists(System.IO.Path.GetDirectoryName(this.AccountsFilePath)))
            {
                Directory.CreateDirectory(System.IO.Path.GetDirectoryName(this.AccountsFilePath));
            }
            AccountsSerializer.DeserializeFromFile(this.AccountsFilePath, ref this.m_Accounts);
            InitializeComponent();
            this.AccountsList.SelectedItem = null;
        }

        private void LinkNewAccount_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Windows.AccountWindow aw = new BinaryDialog.Windows.AccountWindow();
            bool? r = aw.ShowDialog();
            if (r.HasValue && r.Value)
            {
                Regex rgx = new Regex(@"^(([^<>()[\]\\.,;:\s@\""]+"
                    + @"(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@"
                    + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
                    + @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+"
                    + @"[a-zA-Z]{2,}))$");
                string[] jid = rgx.Split(aw.InfoId.Text);
                string password = (aw.InfoSavePassword.IsChecked.Value) ? aw.InfoPassword.Password : string.Empty;
                Int32 port = Convert.ToInt32(aw.InfoPort.Text);
                string screennname = aw.InfoScreenName.Text.Trim();
                bool usessl = aw.InfoSSL.IsChecked.Value;
                bool usetls = aw.InfoStartTLS.IsChecked.Value;
                string nickname = jid[2];
                string server = jid[3];
                if (screennname.Length == 0)
                {
                    screennname = nickname;
                }
                byte[] avatar = null;
                try
                {
                    BitmapFrame bmp = (BitmapFrame)aw.InfoAvatar.Source;
                    PngBitmapEncoder pbe = new PngBitmapEncoder();
                    pbe.Frames.Add(bmp);
                    MemoryStream ms = new MemoryStream();
                    pbe.Save(ms);
                    avatar = BitmapTransform.ImageFileResizedToBytes(ms.ToArray(), 88, 88);
                    if (avatar.Length > 8192)
                    {
                        avatar = null;
                        MessageBox.Show((string)this.FindResource("AvatarTooMoreHeavy"), (string)this.FindResource("MessageBoxErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
                catch
                {
                    avatar = null;
                }
                Account a = new Account(nickname, password, server, port, usessl, usetls);
                a.ScreenName = screennname;
                a.Avatar = avatar;
                this.Accounts.Add(a);
                this.AccountsList.Items.Refresh();
                this.AccountsList.SelectedItem = a;
                this.AccountsList.Focus();
                AccountsSerializer.SerializeToFile(this.Accounts, this.AccountsFilePath);
            }
        }

        private void StartWindow_Closed(object sender, EventArgs e)
        {

        }

        private void StartWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            
        }

        private void LinkDeleteAccount_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (MessageBox.Show((string)this.FindResource("MessageBoxDeleteAccountQuestion"), (string)this.FindResource("MessageBoxQuestionTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
            {
                this.Accounts.Remove((Account)this.AccountsList.SelectedItem);
                this.AccountsList.Items.Refresh();
                this.AccountsList.SelectedItem = null;
                AccountsSerializer.SerializeToFile(this.Accounts, this.AccountsFilePath);
            }
        }

        private void AccountsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.HyperLinkEditAccount != null && this.HyperLinkDeleteAccount != null)
            {
                if (this.AccountsList.SelectedItem != null && this.AccountsList.SelectedItem is Account)
                {
                    this.HyperLinkEditAccount.IsEnabled = true;
                    this.HyperLinkDeleteAccount.IsEnabled = true;
                }
                else
                {
                    this.HyperLinkEditAccount.IsEnabled = false;
                    this.HyperLinkDeleteAccount.IsEnabled = false;
                }
            }
        }

        private void LinkEditAccount_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Account a = (Account)this.AccountsList.SelectedItem;
            Windows.AccountWindow aw = new BinaryDialog.Windows.AccountWindow();
            aw.InfoId.Text = a.NickName + "@" + a.Server;
            aw.InfoPort.Text = a.Port.ToString();
            aw.InfoScreenName.Text = a.ScreenName;
            aw.InfoPassword.Password = a.Password;
            aw.InfoSSL.IsChecked = a.UseSSL;
            aw.InfoStartTLS.IsChecked = a.UseStartTLS;
            if (a.Avatar != null)
            {
                MemoryStream ms = new MemoryStream(a.Avatar);
                BitmapDecoder bd = BitmapDecoder.Create(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                aw.InfoAvatar.Source = bd.Frames[0];
            }
            bool? r = aw.ShowDialog();
            if (r.HasValue && r.Value)
            {
                Regex rgx = new Regex(@"^(([^<>()[\]\\.,;:\s@\""]+"
                    + @"(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@"
                    + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
                    + @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+"
                    + @"[a-zA-Z]{2,}))$");
                string[] jid = rgx.Split(aw.InfoId.Text);
                string password = (aw.InfoSavePassword.IsChecked.Value) ? aw.InfoPassword.Password : string.Empty;
                Int32 port = Convert.ToInt32(aw.InfoPort.Text);
                string screennname = aw.InfoScreenName.Text.Trim();
                bool usessl = aw.InfoSSL.IsChecked.Value;
                bool usetls = aw.InfoStartTLS.IsChecked.Value;
                string nickname = jid[2];
                string server = jid[3];
                if (screennname.Length == 0)
                {
                    screennname = nickname;
                }
                byte[] avatar = null;
                try
                {
                    BitmapFrame bmp = (BitmapFrame)aw.InfoAvatar.Source;
                    PngBitmapEncoder pbe = new PngBitmapEncoder();
                    pbe.Frames.Add(bmp);
                    MemoryStream ms = new MemoryStream();
                    pbe.Save(ms);
                    avatar = BitmapTransform.ImageFileResizedToBytes(ms.ToArray(), 88, 88);
                    if (avatar.Length > 8192)
                    {
                        avatar = null;
                        MessageBox.Show((string)this.FindResource("AvatarTooMoreHeavy"), (string)this.FindResource("MessageBoxErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
                catch
                {
                    avatar = null;
                }
                a.Avatar = avatar;
                a.ScreenName = screennname;
                a.Server = server;
                a.NickName = nickname;
                a.UseSSL = usessl;
                a.UseStartTLS = usetls;
                a.Port = port;
                a.Password = password;
                this.AccountsList.Items.Refresh();
                this.AccountsList.SelectedItem = a;
                this.AccountsList.Focus();
                AccountsSerializer.SerializeToFile(this.Accounts, this.AccountsFilePath);
            }
        }

        private void LinkImportAccounts_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
            ofd.Multiselect = false;
            ofd.AutoUpgradeEnabled = true;
            ofd.RestoreDirectory = true;
            ofd.ShowHelp = false;
            ofd.ShowReadOnly = false;
            ofd.Filter = ((string)this.FindResource("OpenDialogBoxAccountFilter")) + "|*.accounts";
            ofd.FilterIndex = 0;
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    List<Account> acs = new List<Account>();
                    if (AccountsSerializer.DeserializeFromFile(ofd.FileName, ref acs))
                    {
                        foreach (Account a in acs)
                        {
                            bool exists = false;
                            foreach (Account aa in this.Accounts)
                            {
                                if (aa.ToString() == a.ToString())
                                {
                                    exists = true;
                                    break;
                                }
                            }
                            if (!exists)
                            {
                                this.Accounts.Add(a);
                            }
                        }
                        this.AccountsList.Items.Refresh();
                        this.AccountsList.Focus();
                        AccountsSerializer.SerializeToFile(this.Accounts, this.AccountsFilePath);
                    }
                }
                catch
                {
                    MessageBox.Show((string)this.FindResource("MessageBoxImportError"), (string)this.FindResource("MessageBoxErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void LinkExportAccounts_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            System.Windows.Forms.SaveFileDialog ofd = new System.Windows.Forms.SaveFileDialog();
            ofd.AutoUpgradeEnabled = true;
            ofd.RestoreDirectory = true;
            ofd.ShowHelp = false;
            ofd.Filter = ((string)this.FindResource("OpenDialogBoxAccountFilter")) + "|*.accounts";
            ofd.FilterIndex = 0;
            ofd.AddExtension = true;
            ofd.OverwritePrompt = true;
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    if (!AccountsSerializer.SerializeToFile(this.Accounts, ofd.FileName))
                    {
                        throw new Exception();
                    }
                }
                catch
                {
                    MessageBox.Show((string)this.FindResource("MessageBoxExportError"), (string)this.FindResource("MessageBoxErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

    }

}
